package org.easy.tool.common;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;

import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author Valley
 * Created by Valley on 2023/7/14 17:08
 */
public class StringUtil {

    /**
     * 功能：每隔指定位字符，添加一个字符，正序添加
     */
    public static String replaceMark(String origin, int num, String mark) {
        String regex = "(.{"+num+"})";
        origin = origin.replaceAll(regex,"$1"+mark);
        return origin.substring(0,origin.length() - 1);
    }

    /**
     * 功能：每隔指定位字符，添加一个字符，倒序添加
     */
    public static String replaceMarkReverse(String origin, int num, String mark) {
        String reverse = new StringBuilder(origin).reverse().toString();
        String regex = "(.{"+num+"})";
        reverse = reverse.replaceAll(regex,"$1"+mark);
        reverse = new StringBuilder(reverse).reverse().toString();
        if (reverse.startsWith(mark)){
            reverse = reverse.replaceFirst(mark, "");
        }
        return reverse;
    }


    /**
     * 将字符串形式IP地址127.0.0.1转换10234564321
     */
    public static long ip2Long(String strIP) {
        long[] ip = new long[4];
        // 先找到IP地址字符串中.的位置
        int position1 = strIP.indexOf(".");
        int position2 = strIP.indexOf(".", position1 + 1);
        int position3 = strIP.indexOf(".", position2 + 1);
        // 将每个.之间的字符串转换成整型
        ip[0] = Long.parseLong(strIP.substring(0, position1));
        ip[1] = Long.parseLong(strIP.substring(position1 + 1, position2));
        ip[2] = Long.parseLong(strIP.substring(position2 + 1, position3));
        ip[3] = Long.parseLong(strIP.substring(position3 + 1));
        return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
    }

    /**
     *  将字符串形式IP地址转换long类型
     */
    public static long getIp2long(String ip) {
        ip = ip.trim();
        String[] ips = ip.split("\\.");
        long ip1 = Integer.parseInt(ips[0]);
        long ip2 = Integer.parseInt(ips[1]);
        long ip3 = Integer.parseInt(ips[2]);
        long ip4 = Integer.parseInt(ips[3]);
        long ip2long =1L* ip1 * 256 * 256 * 256 + ip2 * 256 * 256 + ip3 * 256 + ip4;
        return ip2long;
    }

    /**
     * 判断一个ip地址是否在某个ip段范围内
     */
    public static boolean isInRangeIP(String ip, String startIP, String endIP) {
        return (getIp2long(startIP)<=getIp2long(ip)) && (getIp2long(ip)<=getIp2long(endIP));
    }

    /**
     * 判断ip是否在指定网段内IP/mask
     */
    public static boolean isInRange(String ip, String cidr) {
        // 以'.'为分隔拆分IP地址存入字符串数组ips
        String[] ips = ip.split("\\.");
        // 通过移位和或运算把IP地址由字符串数组转化为整数
        int ipAddr = (Integer.parseInt(ips[0]) << 24) | (Integer.parseInt(ips[1]) << 16)
                | (Integer.parseInt(ips[2]) << 8) | (Integer.parseInt(ips[3]));
        // 取出指定网段的子网掩码,即'/'后的数字,此为CIDR斜线记法
        int type = Integer.parseInt(cidr.replaceAll(".*/", ""));
        // 转化为整数表示
        int mask = 0xFFFFFFFF << (32 - type);
        // 取出子网IP
        String[] netIps = cidr.replaceAll("/.*", "").split("\\.");
        // 通过移位和或运算把子网IP由字符串数组转化为整数
        int netAddr = (Integer.parseInt(netIps[0]) << 24) | (Integer.parseInt(netIps[1]) << 16)
                | (Integer.parseInt(netIps[2]) << 8) | (Integer.parseInt(netIps[3]));
        // 两个IP分别与掩码做与运算,结果相等则返回True
        return (ipAddr & mask) == (netAddr & mask);
    }

    /**
     * 功能：判断ip地址大小
     */
    public static boolean isBiggerIp(String ip, String compareIp) throws Exception {
        long ipLong = InetAddress.getByName(ip).getHostAddress().hashCode();
        long compare = InetAddress.getByName(compareIp).getHostAddress().hashCode();
        return ipLong > compare;
    }

    /**
     * 功能：判断字符串是不是数字
     */
    public static boolean isNumberStr(String str) {
        return str != null && str.chars().allMatch(Character::isDigit);
    }

    /**
     * 功能：对字符串进行unicode编码
     */
    public static String unicodeStr(String originStr) throws Exception {
        char[] utfBytes = originStr.toCharArray();
        StringBuilder unicodeBytes = new StringBuilder();
        for (char utfByte : utfBytes) {
            String hexB = Integer.toHexString(utfByte);
            if (hexB.length() <= 2) {
                hexB = "00" + hexB;
            }
            unicodeBytes.append("[").append(hexB).append("]");
        }
        return unicodeBytes.toString();
    }

    /**
     * 功能：只对字符串中的中文进行unicode编码
     */
    public static String unicodeStrCN(String originStr) throws Exception {
        char[] utfBytes = originStr.toCharArray();
        StringBuilder unicodeBytes = new StringBuilder();
        for (char utfByte : utfBytes) {
            String hexB = Integer.toHexString(utfByte);
            if (hexB.length() <= 2) {
                unicodeBytes.append(utfByte);
            } else {
                unicodeBytes.append("[").append(hexB).append("]");
            }
        }
        return unicodeBytes.toString();
    }

    /**
     * 功能：替换指定前缀和后缀之间的字符串为某个值
     */
    public static String replaceStr(String origin, String pre, String suf, String value) {
        String[] split = origin.split(pre);
        //如果前缀错误
        if (split.length == 1) return origin;
        String[] sonSplit = split[1].split(suf);
        //如果后缀错误
        if (sonSplit.length == 1) return split[0] + pre + value;
        return split[0] + pre + value + suf + sonSplit[1];
    }

    /**
     * 功能：从指定索引开始截取指定数量字符
     */
    public static String sub(String str, int index, int len) {
        return StrUtil.subWithLength(str, index, len);
    }

    /**
     * 功能：判断两个字符串是否相等
     */
    public static boolean equals(String str1, String str2) {
        return StrUtil.equals(str1, str2);
    }

    /**
     * 功能：判断当前字符串不是空，也不是null
     */
    public static boolean isNotBlank(String str) {
        return StrUtil.isNotBlank(str);
    }

    /**
     * 功能：字符串格式化拼接
     */
    public static String format(String template, Object... args) {
        return StrUtil.format(template, args);
    }

    /**
     * 功能：生成32位随机ID
     */
    public static String randomID() {
        return IdUtil.simpleUUID();
    }

    /**
     * 功能：生成指定长度随机字符串
     */
    public static String random(int len) {
        return RandomUtil.randomString(len);
    }

    /**
     * 功能：取出来所有指定前缀和指定后缀之间的值
     */
    public static List<String> getPreSufStr(String origin, String pre, String suf) {
        List<String> strings = new ArrayList<>();
        if (origin.contains(pre) && origin.contains(suf)) {
            String mark = "PRE_SUF";
            origin = "start" + origin + "end";
            origin = origin.replace(pre, mark)
                    .replace(suf, mark);
            String[] split = origin.split(mark);
            for (int i = 1; i < split.length - 1; i += 2) {
                strings.add(split[i]);
            }
        }
        return strings;
    }

    /**
     * 功能：取出来所有指定前缀和指定后缀分隔开的值，不忽略开头结尾
     */
    public static List<String> getStrByPreSuf(String origin, String pre, String suf) {
        //使用方式
        /*LinkedHashMap<String, List<String>> nameMap = new LinkedHashMap<>();
        for (int i = 1; i <= preSufStr.size(); i++) {
            if (i % 2 == 0) {
                String dbName = preSufStr.get(i-1);
                nameMap.put(dbName, getDataConn(dbName));
            }
        }*/
        List<String> strings = new ArrayList<>();
        if (origin.contains(pre) && origin.contains(suf)) {
            String mark = "PRE_SUF";
            origin = origin.replace(pre, mark)
                    .replace(suf, mark);
            Collections.addAll(strings, origin.split(mark));
        }
        return strings;
    }


}
